/*
 * Copyright Hundsun Technologies Inc. All Rights Reserved.
 */

package contract

import (
	"github.com/golang/protobuf/proto"
	"hundsun.com/hsl/hschain/common/types"
	pbcom "hundsun.com/hsl/hschain/protos/common"
	"hundsun.com/hsl/hschain/store/db"
)

// VersionDB 合约版本存储对象
type VersionDB struct {
	get db.DatabaseGet
}

// NewContractVesionDB new ContractVesionDB
func NewContractVesionDB(get db.DatabaseGet) *VersionDB {
	return &VersionDB{get: get}
}

// GetContractVersion get ContractVesion from name
func (ctver *VersionDB) GetContractVersion(name string) (*pbcom.ContractVersion, error) {
	if ctver.get == nil {
		return nil, types.ErrNotFound
	}
	v, err := ctver.get.Get(GenContractVersionKey(name))
	if err != nil {
		return nil, err
	}
	ver := &pbcom.ContractVersion{}
	err = proto.Unmarshal(v, ver)
	if err != nil {
		return nil, err
	}
	return ver, nil
}

// GetContractVersions get ContractVersions from names
func (ctver *VersionDB) GetContractVersions(names []string) ([]*pbcom.ContractVersion, error) {
	if ctver.get == nil {
		return nil, types.ErrNotFound
	}
	keys := make([][]byte, len(names))
	for i, key := range names {
		keys[i] = GenContractVersionKey(key)
	}
	values, err := ctver.get.Gets(keys)
	if err != nil {
		return nil, err
	}
	var ctvers []*pbcom.ContractVersion
	for _, v := range values {
		ver := &pbcom.ContractVersion{}
		err = proto.Unmarshal(v, ver)
		if err != nil {
			continue
		}
		ctvers = append(ctvers, ver)
	}
	return ctvers, nil
}

// VersionKV from ContractVersion to kv
func VersionKV(ctver *pbcom.ContractVersion) (*pbcom.KeyValue, error) {
	kv := &pbcom.KeyValue{}
	kv.Key = GenContractVersionKey(ctver.Name)
	v, err := proto.Marshal(ctver)
	if err != nil {
		return nil, err
	}
	kv.Value = v
	return kv, nil
}

// GenContractVersionKey generate ContractVersion key
func GenContractVersionKey(name string) []byte {
	return []byte(db.NamespaceContractVersion + name)
}
